﻿using Furion.DependencyInjection;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json.Linq;

namespace GMS.NET.Core.Provider.CacheProvider
{
    /// <summary>
    /// 
    /// </summary>
    public class Memory : ICachingService, ISingleton
    {
        private readonly IMemoryCache _memoryCache;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="memoryCache"></param>
        public Memory(IMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public Task<bool> AnyAsync(string key)
        {
            try
            {
               return Task.FromResult( _memoryCache.TryGetValue(key,out object? outValue));
            }
            catch (Exception){ return Task.FromResult(false);  }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public  Task<T> GetAsync<T>(string key)
        {
            try
            {
                return Task.FromResult(_memoryCache.Get<T>(key)!);
            }
            catch (Exception) { return Task.FromResult(default(T)!); }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public  Task<string> GetStringAsync(string key)
        {
            try
            {
                return Task.FromResult(_memoryCache.Get(key)!.ToString()!);
            }
            catch (Exception) { return Task.FromResult(string.Empty); }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        public void Remove(string key)
        {
            try
            {
                _memoryCache.Remove(key);
            }
            catch (Exception) { }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="absoluteExpirationRelativeToNow"></param>
        public void Set<T>(string key, T value, TimeSpan absoluteExpirationRelativeToNow)
        {
            try
            {
                _memoryCache.GetOrCreate(key, entry =>
                {
                    entry.SlidingExpiration = absoluteExpirationRelativeToNow;  // 滑动缓存时间
                    return value;
                });
            }
            catch (Exception) { }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="absoluteExpirationRelativeToNow"></param>
        /// <returns></returns>
        public async Task SetAsync<T>(string key, T value, TimeSpan absoluteExpirationRelativeToNow)
        {
            try
            {
                await _memoryCache.GetOrCreateAsync<T>(key, async entry =>
                {
                    entry.SlidingExpiration = absoluteExpirationRelativeToNow;  // 滑动缓存时间
                    return value;
                });
            }
            catch (Exception) { }
        }
    }
}
